package com.yanqu.road.server.manger.activity.shushan;

import com.yanqu.road.entity.activity.args.ConditionTypeValueArgs;
import com.yanqu.road.entity.activity.shushan.*;
import com.yanqu.road.entity.activity.shushan.config.*;
import com.yanqu.road.entity.config.goods.OpenGoodsBagResult;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSexType;
import com.yanqu.road.entity.log.*;
import com.yanqu.road.logic.bussiness.activity.ShuShanBusiness;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.pb.activity.ShuShanProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.NameMgr;
import com.yanqu.road.server.manger.config.GoodsBagMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description
 * @Author cwq
 * @Data 2022/3/8 16:47
 */
public class ShuShanUserInfo {

    private ShuShanUserData shuShanUserData;

    /**
     * 最大的弟子id
     */
    private AtomicInteger maxId = new AtomicInteger(0);

    /**
     * 弟子
     */
    private Map<Integer, ShuShanDiscipleData> discipleDataMap = new ConcurrentHashMap<>();

    /**
     * 弟子
     */
    private Map<Integer, ShuShanDiscipleData> deleteDiscipleDataMap = new ConcurrentHashMap<>();

    /**
     * 建筑
     */
    private Map<Integer, ShuShanBuildData> buildDataMap = new ConcurrentHashMap<>();

    /**
     * 历练格子信息
     */
    private Map<Integer, ShuShanLiLianGridData> liLianGridDataMap = new ConcurrentHashMap<>();


    public void save() {
        if (shuShanUserData.isInsertOption()) {
            ShuShanBusiness.addShuShanUserData(shuShanUserData);
        } else if (shuShanUserData.isUpdateOption()) {
            ShuShanBusiness.updateShuShanUserData(shuShanUserData);
        }
        for (ShuShanBuildData item : buildDataMap.values()) {
            if (item.isInsertOption()) {
                ShuShanBusiness.addShuShanBuildData(item);
            } else if (item.isUpdateOption()) {
                ShuShanBusiness.updateShuShanBuildData(item);
            }
        }
        for (ShuShanDiscipleData item : discipleDataMap.values()) {
            if (item.isInsertOption()) {
                ShuShanBusiness.addShuShanDiscipleData(item);
            } else if (item.isUpdateOption()) {
                ShuShanBusiness.updateShuShanDiscipleData(item);
            }
        }
        Map<Integer, ShuShanDiscipleData> tempDeleteDiscipleDataMap = null;
        synchronized (deleteDiscipleDataMap) {
            tempDeleteDiscipleDataMap = new ConcurrentHashMap<>(deleteDiscipleDataMap);
            deleteDiscipleDataMap.clear();
        }
        for (ShuShanDiscipleData item : tempDeleteDiscipleDataMap.values()) {
            if (item.isInsertOption()) {
                ShuShanBusiness.addShuShanDiscipleData(item);
            } else if (item.isUpdateOption()) {
                ShuShanBusiness.updateShuShanDiscipleData(item);
            }
        }

        for (ShuShanLiLianGridData item : liLianGridDataMap.values()) {
            if (item.isInsertOption()) {
                ShuShanBusiness.addShuShanLiLianGridData(item);
            } else if (item.isUpdateOption()) {
                ShuShanBusiness.updateShuShanLiLianGridData(item);
            }
        }

    }


    public ShuShanUserInfo(ShuShanUserData shuShanUserData) {
        this.shuShanUserData = shuShanUserData;
    }

    /**
     * 离开系统
     */
    public void exit() {
        shuShanUserData.setExitTime(DateHelper.getCurrentSecond());
    }

    /**
    * 描述：蜀山取名，如果是管理员操作则不设置操作时间
    * 作者：zrq
    * 时间：2022/8/5
    * 参数：
    名称，是否管理员操作
    * 返回值：
    **/
    public void takeName(String name, boolean isAdminOp) {
        shuShanUserData.setPartyName(name);
        if(!isAdminOp) {
            shuShanUserData.setTakeNameTime(DateHelper.getCurrentSecond());
        }
    }

    public boolean canTakeName() {
        return shuShanUserData.getTakeNameTime() <= 0;
    }

    /**
     * 判断是否能够修炼该建筑
     *
     * @param disciple
     * @param build
     * @return
     */
    private boolean canExerciseThisBuild(ShuShanDiscipleData disciple, ShuShanBuildData build) {
        if (build.getCurDiscipleId() > 0) {
            // 正在修炼该建筑
            return false;
        }
        List<ShuShanBuildConfig> maxSkillBuildList = getTheBuildMaxSkillList(build);
        for (ShuShanBuildConfig config : maxSkillBuildList) {

            if (canLearnThisSkill(disciple, build, config)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取当前等级建筑 各个技能等级最大的配置
     *
     * @return
     */
    private List<ShuShanBuildConfig> getTheBuildMaxSkillList(ShuShanBuildData build) {
        List<ShuShanBuildConfig> list = ShuShanMgr.getConfig().getTypeLevelBuildListMap().get(build.getType());
        // 已解锁技能 最大的技能配置
        Map<Integer, ShuShanSkillConfig> skillMap = new HashMap<>();
        //
        Map<Integer, ShuShanBuildConfig> maxSkillBuildMap = new HashMap<>();
        for (ShuShanBuildConfig config : list) {
            if (build.getLevel() < config.getLevel()) {
                // 未解锁
                break;
            }
            int skillId = Integer.valueOf(config.getParam());
            ShuShanSkillConfig skillConfig = ShuShanMgr.getConfig().getSkillConfigMap().get(skillId);
            if (skillConfig != null) {
                ShuShanSkillConfig tempSkillConfig = skillMap.get(skillConfig.getLittleType());
                if (tempSkillConfig == null || skillConfig.getLevel() > tempSkillConfig.getLevel()) {
                    skillMap.put(skillConfig.getLittleType(), skillConfig);
                    maxSkillBuildMap.put(skillConfig.getLittleType(), config);
                }
            }
        }

        List<ShuShanBuildConfig> maxSkillBuildList = new ArrayList<>(maxSkillBuildMap.values());
        maxSkillBuildList.sort((t1, t2) -> {
            return Integer.compare(t1.getLevel(), t2.getLevel());
        });
        return maxSkillBuildList;
    }


    /**
     * 判断是能能够学习该技能
     *
     * @return
     */
    private boolean canLearnThisSkill(ShuShanDiscipleData disciple, ShuShanBuildData build, ShuShanBuildConfig config) {
        if (build.getLevel() < config.getLevel()) {
            // 未解锁
            return false;
        }
        int skillId = Integer.valueOf(config.getParam());

        ShuShanSkillConfig skillConfig = ShuShanMgr.getConfig().getSkillConfigMap().get(skillId);
        // 这个技能已学到的等级
        int level = getDiscipleSkillLevel(disciple, build.getType(), skillConfig.getLittleType(), false);

        if (level < skillConfig.getLevel()) {
            return true;
        }
        return false;
    }


    /**
     * 可拥有的弟子最大上限
     *
     * @return
     */
    private int getDiscipleMaxLimit() {
        int level = getBuildLevel(eShuShanBuildType.type_6.getType());
        ShuShanBuildConfig buildConfig = ShuShanMgr.getConfig().getTypeLevelBuildMap().get(eShuShanBuildType.type_6.getType()).get(level);
        if (buildConfig != null) {
            return buildConfig.getMaxStudent();
        }
        return 0;
    }

    /**
     * 选拔 随机弟子品质
     * 品质从0开始
     *
     * @return
     */
    private int randomDiscipleQuality() {
        // 优先指定次数
        if (shuShanUserData.getRandomDiscipleNum() < ShuShanMgr.getConfig().getRandomDiscipleQualityList().size()) {
            return ShuShanMgr.getConfig().getRandomDiscipleQualityList().get(shuShanUserData.getRandomDiscipleNum());
        }
        // 再保底次数
        for (Map.Entry<Integer, Integer> entry : ShuShanMgr.getConfig().getBaoDiMap().entrySet()) {
            int quality = entry.getKey();
            int unTriggerTimes = shuShanUserData.getUnTriggerQualityMap().getOrDefault(quality, 0);
            if (unTriggerTimes >= entry.getValue() - 1) {
                return quality;
            }
        }
        ShuShanBuildConfig config = getShuShanBuildConfigType7();
        if (config != null) {
            return WeightHelper.getRandomValue(config.getWeightMap());
        }
        return 0;
    }

    /**
     * 通过属性计算品质
     *
     * @return
     */
    private int getDiscipleQuality(int totalValue) {
        int quality = 0;
        for (Object[] objects : ShuShanMgr.getConfig().getPowerQuiltList()) {
            quality = (int) (objects[0]);
            List<Integer> list = (List<Integer>) objects[1];
            if (list.get(0) < totalValue && totalValue <= list.get(1)) {
                break;
            }
        }
        return quality;
    }

    /**
     * 获取 自己等级山门的配置
     *
     * @return
     */
    private ShuShanBuildConfig getShuShanBuildConfigType7() {
        Map<Integer, ShuShanBuildConfig> map = ShuShanMgr.getConfig().getTypeLevelBuildMap().get(eShuShanBuildType.type_7.getType());
        if (map != null) {
            // 山门等级
            ShuShanBuildData buildData = buildDataMap.get(eShuShanBuildType.type_7.getType());
            if (buildData != null) {
                return map.get(buildData.getLevel());
            }
        }
        return null;
    }

    /**
     * 随机属性
     *
     * @return
     */
    private int randomDisciplePropertiesInfo(ShuShanDiscipleBaseInfo discipleBaseInfo) {
        int quality = randomDiscipleQuality();
        // 先根据品质随机 仙力
        List<Integer> list = ShuShanMgr.getConfig().getPowerQuiltMap().get(quality);
        // 仙力总值
        int totalValue = list.get(0) + ShuShanMgr.getRandom().nextInt(list.get(1) - list.get(0)) + 1;
        Map<Integer, Double> weightMap = new HashMap<>();
        double totalWeight = 0;
        for (int skill : ShuShanMgr.getConfig().getSkillTypeConfigMap().keySet()) {
            // 放大一百倍
            double b = ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_PARAM_F() / 100d * ShuShanMgr.getRandom().nextDouble() + ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_PARAM_BASE() / 100d;
            // 放大一百倍
            double b1 = Math.pow(ShuShanMgr.getRandom().nextDouble(), ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_PARAM_EX_2() / 100d);
            double weight = ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_PARAM_EX_2() * Math.max(b, b1);
            weightMap.put(skill, weight);
            totalWeight += weight;
        }
        int realValue = 0;
        Map<Integer, Integer> propertiesInfoMap = new HashMap<>();
        for (Map.Entry<Integer, Double> entry : weightMap.entrySet()) {
            int value = 0;
            if (propertiesInfoMap.size() == ShuShanMgr.getConfig().getSkillTypeConfigMap().keySet().size() - 1) {
                // 最后一个
                int beforeValue = 0;
                for (int v : propertiesInfoMap.values()) {
                    beforeValue += v;
                }
                value = Math.max(1, totalValue - beforeValue);
                propertiesInfoMap.put(entry.getKey(), value);
            } else {
                value = (int) (Math.max(1, Math.round(entry.getValue() * totalValue / totalWeight)));
                propertiesInfoMap.put(entry.getKey(), value);
            }
            realValue += value;
        }
//        // 矫正品质
//        int realQuality = getDiscipleQuality(realTotalValue);
//        ShuShanMgr.getLogger().info("蜀山活动id：{}，选拔随机属性打印，玩家id：{}，随机的品质：{},随机后的属性总值：{},权重：{}，属性各值：{},实际总值：{}", shuShanUserData.getActivityId(), shuShanUserData.getUserId(), quality, totalValue, JSON.toJSONString(weightMap), JSON.toJSONString(propertiesInfoMap), realValue);
        discipleBaseInfo.setQuality(quality);
        discipleBaseInfo.setPropertiesInfoMap(propertiesInfoMap);
        return realValue;
    }

    /**
     * 进入 系统
     *
     * @return
     */
    public ShuShanProto.ShuShanEnterRespMsg.Builder enter() {
        ShuShanProto.ShuShanEnterRespMsg.Builder builder = ShuShanProto.ShuShanEnterRespMsg.newBuilder();
        int now = DateHelper.getCurrentSecond();
        int exitTime = now - shuShanUserData.getExitTime();
        if (shuShanUserData.getOffLineExerciseInfoMap().size() > 0 && exitTime >= ShuShanMgr.getConfig().getSHUSHAN_OFF_TIME_LIMIT() * DateHelper.MINUTE_SECONDS) {
            ShuShanProto.ShuShanOfflineExerciseInfo.Builder offlineExercise = ShuShanProto.ShuShanOfflineExerciseInfo.newBuilder();
            offlineExercise.setOffLineTime(now - shuShanUserData.getExitTime());
            for (Map.Entry<Integer, ShuShanExerciseInfo> entry : shuShanUserData.getOffLineExerciseInfoMap().entrySet()) {
                ShuShanProto.ShuShanExerciseInfo.Builder exerciseInfo = ShuShanProto.ShuShanExerciseInfo.newBuilder();
                exerciseInfo.setDiscipleId(entry.getKey());
                exerciseInfo.setExerciseTimes(entry.getValue().getTimes());
                exerciseInfo.addAllSkillId(entry.getValue().getSkillList());
                offlineExercise.addExerciseList(exerciseInfo);
            }
            builder.setOfflineExerciseInfo(offlineExercise);
        }
        shuShanUserData.getOffLineExerciseInfoMap().clear();
        shuShanUserData.setUpdateOption();
        // 玩家数据
        builder.setUserInfo(buildShuShanUserInfo());
        // 建筑数据
        builder.addAllBuildInfoList(buildShuShanBuildInfoList());
        // 弟子数据
        builder.addAllOwnDiscipleList(buildShuShanDiscipleInfoList());
        // 历练格子
        liLianGridDataMap.values().forEach(e -> {
            builder.addLiLianInfoGridList(builderShuShanLiLianGridInfo(e));
        });
        builder.setRet(0);
        return builder;
    }

    /**
     * 刷新选拔次数
     *
     * @param forceUpdate
     */
    public void refreshGetTimes(boolean forceUpdate) {
        // 刷新选拔次数
        int now = DateHelper.getCurrentSecond();
        int diff = now - shuShanUserData.getGetRefreshTime();
        if (shuShanUserData.getGetTimes() < ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_MAX()) {
            int cd = (int) (ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_CD() * DateHelper.MINUTE_SECONDS);
            int timesCD = (int) (diff / cd);
            if (timesCD > 0) {
                int times = timesCD * ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_NUM();
                if (times + shuShanUserData.getGetTimes() < ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_MAX()) {
                    shuShanUserData.setGetTimes(shuShanUserData.getGetTimes() + times);
                    shuShanUserData.setGetRefreshTime(shuShanUserData.getGetRefreshTime() + timesCD * cd);
                } else {
                    shuShanUserData.setGetRefreshTime(now);
                    shuShanUserData.setGetTimes(ShuShanMgr.getConfig().getSHUSHAN_SHANMEN_SHUA_MAX());
                }
            }
        } else {
            if (forceUpdate) {
                shuShanUserData.setGetRefreshTime(now);
            }
        }
    }

    /**
     * 刷新 每日刷新已购买选拔次数时间
     */
    public void refreshBuyGetRefreshTime() {
        if (DateHelper.getDiffDayNum(shuShanUserData.getBuyGetRefreshTime()) != 0) {
            shuShanUserData.setBuyGetTimes(0);
            shuShanUserData.setBuyGetRefreshTime(DateHelper.getCurrentSecond());
        }
    }

    /**
     * 刷新弟子修炼信息
     *
     * @param now s
     */
    public synchronized void refreshExercise(int now) {
        // 结算当前的坑位  如果有结算补上 坑位再尝试结算
        if (now > ShuShanMgr.getActivityInfo().getEndTime()) {
            return;
        }
        while (true) {
            // 结算坑位
            boolean isSettlement = attemptSettlementBuild(now);
            boolean isEnter = attemptEnterBuild();
            if (!isSettlement || !isEnter) {
                break;
            }
        }
    }


    /**
     * 尝试结算建筑
     *
     * @param now s
     * @return 返回是否有空位置
     */
    private boolean attemptSettlementBuild(int now) {
        // 是否有空位置结算
        boolean isSettlement = false;
        // 是否有学习成功
        boolean isSyn = false;
        for (ShuShanBuildData build : buildDataMap.values()) {
            if (build.getCurDiscipleId() > 0 && now > build.getExerciseStartTime()) {
                ShuShanDiscipleData disciple = discipleDataMap.get(build.getCurDiscipleId());
                Iterator<ShuShanExerciseSuccessNode> iterator = build.getSuccessNodeList().iterator();
                while (iterator.hasNext()) {
                    ShuShanExerciseSuccessNode node = iterator.next();
                    int endTime = node.getExerciseEndTime();
                    if (now >= endTime) {
                        isSyn = true;
                        iterator.remove();
                        if (learnBuildSkill(disciple, build, node, node.getExerciseEndTime(), !iterator.hasNext(), false, now)) {
                            isSettlement = true;
                        }
                    } else {
                        break;
                    }
                }
            }
        }
        // 同步玩家数据
        if (!ShuShanMgr.getInActivitySet().contains(shuShanUserData.getUserId()) && isSyn) {
            // 不在活动里面才需要同步
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(shuShanUserData.getUserId());
            ShuShanMgr.synUserData(player, true);
        }
        return isSettlement;
    }


    /**
     * @param disciple
     * @param build
     * @param node
     * @param learnedEndTime 实际学习结束时间
     * @param allLearned
     * @return
     */
    private boolean learnBuildSkill(ShuShanDiscipleData disciple, ShuShanBuildData build, ShuShanExerciseSuccessNode node, int learnedEndTime, boolean allLearned, boolean isUpBuild, int now) {
        // 已解锁的技能都学完了 加属性
        ShuShanSkillConfig skillConfig = ShuShanMgr.getConfig().getSkillConfigMap().get(node.getKillId());
        if (skillConfig == null) {
            return false;
        }
        Map<Integer, Integer> map = disciple.getLearnedSkillMap().get(build.getType());
        if (map == null) {
            map = new HashMap<>();
            disciple.getLearnedSkillMap().put(build.getType(), map);
        }
        int oldLevel = map.getOrDefault(skillConfig.getLittleType(), 0);
        if (oldLevel >= skillConfig.getLevel()) {
            return false;
        }
        map.put(skillConfig.getLittleType(), skillConfig.getLevel());
        disciple.setUpdateOption();
        // 加离线数据
        if (!ShuShanMgr.getInActivitySet().contains(shuShanUserData.getUserId())) {
            if (learnedEndTime > shuShanUserData.getExitTime()) {
                int diffTime = learnedEndTime - shuShanUserData.getExitTime();
                int cd = ShuShanMgr.getConfig().getLearnCDMap().get(disciple.getQuality());
                int times = (diffTime + cd - 1) / cd;
                addOffLineExerciseTimes(disciple.getId(), times, node.getKillId());
            }
        }
        long oldValue = getPropertiesTotalValue(disciple.getPropertiesInfoMap());
        Map<Integer, ShuShanPropertiesInfo> oldPropertiesInfo = new HashMap<>(disciple.getPropertiesInfoMap());
//        ShuShanMgr.getLogger().info("蜀山学习完成打印。活动id:{},玩家id:{},弟子id:{},建筑id：{}，学习的技能id:{},开始学习时间：{}，预计结束时间：{}，需要学习的次数：{}，快速修行的次数：{}，是否因为建筑升级完成：{}，学习完成时间：{}", shuShanUserData.getActivityId(), shuShanUserData.getUserId(), disciple.getId(), build.getType(), node.getKillId(), node.getExerciseStartTime(), node.getExerciseEndTime(), node.getTimes(), node.getGoodExerciseTimes(), isUpBuild, learnedEndTime);
        refreshDisciple(disciple, learnedEndTime, skillConfig);
        disciple.setLastLearnedTime(learnedEndTime);
        LogMgr.addLogShuShanExerciseRecord(new LogShuShanExerciseRecord(shuShanUserData.getActivityId(), shuShanUserData.getUserId(), disciple.getId(), node.getKillId(), node.getTimes(), node.getGoodExerciseTimes(), isUpBuild, oldValue, oldPropertiesInfo, getPropertiesTotalValue(disciple.getPropertiesInfoMap()), new HashMap<>(disciple.getPropertiesInfoMap()), learnedEndTime, now));
        build.setUpdateOption();
        if (allLearned) {
            // 判断是否学完
            build.setFreeTime(learnedEndTime);
            build.setCurDiscipleId(0);
            build.getSuccessNodeList().clear();
            build.setExerciseStartTime(0);
            return true;
        }
        return false;
    }

    /**
     * 尝试进入建筑修炼
     */
    private boolean attemptEnterBuild() {
        boolean isEnter = false;
        // 空闲的弟子排序
        List<ShuShanDiscipleData> canExerciseDiscipleList = getFreeDiscipleList();
        if (canExerciseDiscipleList.size() <= 0) {
            return false;
        }
        List<ShuShanBuildData> freeBuildList = getFreeBuildList();
        if (freeBuildList.size() <= 0) {
            return false;
        }
        Iterator<ShuShanBuildData> freeBuildIterator = freeBuildList.iterator();
        while (freeBuildIterator.hasNext()) {
            ShuShanBuildData build = freeBuildIterator.next();
            for (int i = 0; i < canExerciseDiscipleList.size(); i++) {
                ShuShanDiscipleData disciple = canExerciseDiscipleList.get(i);
                if (canExerciseThisBuild(disciple, build)) {
                    // 进入学习改技能
                    canExerciseDiscipleList.remove(i);
                    freeBuildIterator.remove();
                    learnBuild(build, disciple);
                    isEnter = true;
                    break;
                }
            }
        }
        return isEnter;
    }

    /**
     * 进入建筑学习
     */
    private void learnBuild(ShuShanBuildData build, ShuShanDiscipleData disciple) {
        List<ShuShanBuildConfig> maxSkillBuildList = getTheBuildMaxSkillList(build);
        for (ShuShanBuildConfig config : maxSkillBuildList) {
            if (build.getLevel() < config.getLevel()) {
                // 未解锁
                break;
            }
            if (!canLearnThisSkill(disciple, build, config)) {
                // 已学过
                continue;
            }
            int skillId = Integer.valueOf(config.getParam());
            // 正在学习
            boolean learning = false;
            for (ShuShanExerciseSuccessNode node : build.getSuccessNodeList()) {
                if (node.getKillId() == skillId) {
                    learning = true;
                    break;
                }
            }
            if (learning) {
                continue;
            }
            ShuShanSkillConfig skillConfig = ShuShanMgr.getConfig().getSkillConfigMap().get(skillId);
            int p = skillConfig.getStudyP();
            if (skillConfig.getStudyP() <= 0) {
                // 加个保护
                p = 1;
            }
            // 修炼成功需要的时间
            int startTime = 0;
            if (build.getSuccessNodeList().size() == 0) {
                startTime = Math.max(build.getFreeTime(), disciple.getLastLearnedTime());
                build.setExerciseStartTime(startTime);
            } else {
                startTime = build.getSuccessNodeList().get(build.getSuccessNodeList().size() - 1).getExerciseEndTime();
            }
            long endTime = startTime;
            int cd = ShuShanMgr.getConfig().getLearnCDMap().get(disciple.getQuality());
            if(cd <= 0){
                // 加个保护
                return;
            }
            endTime += cd;
            int times = 1;
            while (ShuShanMgr.getRandom().nextInt(1000) >= p) {
                endTime += cd;
                times++;
                // 加个保护
                if (endTime > ShuShanMgr.getActivityInfo().getEndShowTime()) {
                    break;
                }
            }
            ShuShanExerciseSuccessNode node = new ShuShanExerciseSuccessNode();
            node.setKillId(skillId);
            node.setExerciseStartTime(startTime);
            node.setExerciseEndTime((int) endTime);
            node.setTimes(times);
            build.getSuccessNodeList().add(node);
            build.setCurDiscipleId(disciple.getId());
//            ShuShanMgr.getLogger().info("蜀山进入建筑学习打印。活动id:{},玩家id:{},弟子id:{},建筑id：{}，学习的技能id:{},开始学习时间：{}，需要学习的次数：{}，概率：{}，结束时间：{}", shuShanUserData.getActivityId(), shuShanUserData.getUserId(), disciple.getId(), build.getType(), skillConfig.getId(), startTime, times, p, endTime);
        }
    }

    /**
     * 刷新 某个技能加成
     *
     * @param disciple
     * @param endTime
     * @param skillConfig
     * @return
     */
    private boolean refreshDisciple(ShuShanDiscipleData disciple, int endTime, ShuShanSkillConfig skillConfig) {
        boolean change = false;
        // 重新计算弟子的属性
        Map<Integer, Integer> skillLevelMap = disciple.getLearnedSkillMap().get(skillConfig.getType());
        if(skillLevelMap == null){
            return false;
        }
        Map<Integer, Map<Integer, ShuShanSkillConfig>> typeSkillLevelMap = ShuShanMgr.getConfig().getTypeLevelConfigMap().get(skillConfig.getType());
        long addPlus = 0;
        for (Map.Entry<Integer, Integer> entry : skillLevelMap.entrySet()) {
            Map<Integer, ShuShanSkillConfig> levelSkillMap = typeSkillLevelMap.get(entry.getKey());
            ShuShanSkillConfig levelSkillConfig = levelSkillMap.get(entry.getValue());
            addPlus += levelSkillConfig.getAdd();
        }
        if (addPlus > 0) {
            ShuShanPropertiesInfo propertiesInfo = disciple.getPropertiesInfoMap().get(skillConfig.getType());
            if (propertiesInfo != null) {
                long addValue = propertiesInfo.getBaseValue() * addPlus / 1000;
                if (addValue != propertiesInfo.getAddValue()) {
                    propertiesInfo.setAddValue(addValue);
                    change = true;
                    refreshTotalMagic();
                    // 判断该弟子历练的格子 是否有新的历练 刷新并且 同步给客户端
                    ShuShanLiLianGridData gridData = getShuShanLiLianGridData(disciple);
                    if (gridData != null) {
                        refreshLiLianGrid(gridData, endTime);
                    }
                }
            }
        }
        return change;
    }

    /**
     * 弟子是否学习了所有技能
     *
     * @param discipleData
     * @return
     */
    private boolean isLearnAllSkills(ShuShanDiscipleData discipleData) {
        for(Map.Entry<Integer, Map<Integer, List<ShuShanSkillConfig>>> entry : ShuShanMgr.getConfig().getTypeLevelConfigListMap().entrySet()){
            int type = entry.getKey();
            Map<Integer, Integer> map = discipleData.getLearnedSkillMap().get(type);
            if (map == null){
                return false;
            }
            for (Map.Entry<Integer, List<ShuShanSkillConfig>> item : entry.getValue().entrySet()){
                if(item.getValue().size() <= 0){
                    continue;
                }
                int level = map.getOrDefault(item.getKey(),0);
                if(level < item.getValue().get(item.getValue().size() - 1).getLevel()){
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 弟子是否属于空闲状态 (不在学习)
     *
     * @param discipleData
     * @return
     */
    private boolean isFree(ShuShanDiscipleData discipleData) {
        for (ShuShanBuildData item : buildDataMap.values()) {
            if (item.getCurDiscipleId() == discipleData.getId()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 添加离线修炼次数
     *
     * @param id
     * @param times
     */
    private void addOffLineExerciseTimes(int id, int times, int skillId) {
        if (!ShuShanMgr.getInActivitySet().contains(shuShanUserData.getUserId())) {
            ShuShanExerciseInfo exerciseInfo = shuShanUserData.getOffLineExerciseInfoMap().get(id);
            if (exerciseInfo == null) {
                exerciseInfo = new ShuShanExerciseInfo();
                shuShanUserData.getOffLineExerciseInfoMap().put(id, exerciseInfo);
            }
            exerciseInfo.setTimes(exerciseInfo.getTimes() + times);
            if (skillId != 0) {
                exerciseInfo.getSkillList().add(skillId);
            }
        }
    }

    /**
     * 获取空闲弟子的集合 并排序
     *
     * @return
     */
    private List<ShuShanDiscipleData> getFreeDiscipleList() {
        List<ShuShanDiscipleData> canExerciseDiscipleList = new ArrayList<>();
        for (ShuShanDiscipleData item : discipleDataMap.values()) {
            if (isFree(item) && !isLearnAllSkills(item)) {
                canExerciseDiscipleList.add(item);
            }
        }
        // 空闲时间排序
        canExerciseDiscipleList.sort((t1, t2) -> {
            // 空闲的时间
            if (t1.getLastLearnedTime() != t2.getLastLearnedTime()) {
                return Integer.compare(t1.getLastLearnedTime(), t2.getLastLearnedTime());
            }
            return Integer.compare(t1.getId(), t2.getId());
        });
        return canExerciseDiscipleList;
    }

    /**
     * 获取空闲建筑的集合 并排序
     *
     * @return
     */
    private List<ShuShanBuildData> getFreeBuildList() {
        List<ShuShanBuildData> freeBuildList = new ArrayList<>();
        for (ShuShanBuildData item : buildDataMap.values()) {
            if (item.getType() <= eShuShanBuildType.type_5.getType() && item.getCurDiscipleId() <= 0) {
                freeBuildList.add(item);
            }
        }
        // 空闲时间排序
        Collections.shuffle(freeBuildList);
        freeBuildList.sort((t1, t2) -> {
            // 空闲的时间
            return Integer.compare(t1.getFreeTime(), t2.getFreeTime());
        });
        return freeBuildList;
    }


    /**
     * 刷新历练格子
     *
     * @param now
     */
    public void refreshLiLianGrid(int now) {
        if (now > ShuShanMgr.getActivityInfo().getEndTime()) {
            return;
        }
        for (ShuShanLiLianGridData item : liLianGridDataMap.values()) {
            refreshLiLianGrid(item, now);
        }
    }


    /**
     * 刷新历练格子
     */
    private void refreshLiLianGrid(ShuShanLiLianGridData grid, int now) {
        while (true) {
            if (now > ShuShanMgr.getActivityInfo().getEndTime() || now < grid.getEndTime()) {
                return;
            }
            ShuShanDiscipleData disciple = discipleDataMap.get(grid.getCurDiscipleId());
            if (disciple == null) {
                return;
            }
            if (grid.getEndTime() != 0) {
                if (!attemptEndLiLian(grid, disciple, now)) {
                    return;
                }
            } else {
                // 判断是否开始修炼
                if (!attemptStartLiLian(grid, disciple, now)) {
                    return;
                }
            }
        }
    }

    /**
     * 获取当前可以 或正在修炼的遭遇
     */
    private ShuShanRewardConfig getCurCanLiLianGridConfig(ShuShanLiLianGridData grid) {
        List<ShuShanRewardConfig> list = ShuShanMgr.getConfig().getActivityConditionInfoList(grid.getGridId());
        if (list == null || list.size() <= 0) {
            return null;
        }
        if (list.get(list.size() - 1).getId() == grid.getLastFinishId()) {
            // 完成所有遭遇
            return null;
        }
        // 获取当前可以 或正在修炼的遭遇
        ShuShanRewardConfig rewardConfig = null;
        for (ShuShanRewardConfig item : list) {
            if (item.getId() > grid.getLastFinishId()) {
                rewardConfig = item;
                break;
            }
        }
        return rewardConfig;
    }

    /**
     * 尝试修炼历练
     *
     * @param grid
     * @param disciple
     * @param startTime
     * @return
     */
    private boolean attemptStartLiLian(ShuShanLiLianGridData grid, ShuShanDiscipleData disciple, int startTime) {
        ShuShanRewardConfig rewardConfig = getCurCanLiLianGridConfig(grid);
        if (rewardConfig != null) {
            long value = 0;
            if (rewardConfig.getPowerType() == 0) {
                // 总仙力
                value = getPropertiesTotalValue(disciple.getPropertiesInfoMap());
            } else {
                value = getPropertiesOneValue(disciple, rewardConfig.getPowerType());
            }
            if (value < rewardConfig.getPower()) {
                // 不满足条件
                return false;
            }
            int time = 0;
            if (grid.getRemainTime() > 0) {
                time = grid.getRemainTime();
                grid.setRemainTime(0);
            } else {
                time = rewardConfig.getCosttime();
            }
            grid.setEndTime(startTime + time);
            return true;
//            ShuShanMgr.getLogger().info("蜀山开始修炼遭遇。活动id:{},玩家id:{},弟子id:{},格子id：{}，遭遇id:{},开始时间：{}，结束时间：{}", shuShanUserData.getActivityId(), shuShanUserData.getUserId(), disciple.getId(), grid.getGridId(), rewardConfig.getId(), startTime, grid.getEndTime());
        }
        return false;
    }

    /**
     * 尝试结束历练
     *
     * @return
     */
    private boolean attemptEndLiLian(ShuShanLiLianGridData grid, ShuShanDiscipleData disciple, int now) {
        int endTime = grid.getEndTime();
        if (endTime > 0 && now > endTime) {
            ShuShanRewardConfig rewardConfig = getCurCanLiLianGridConfig(grid);
            if (rewardConfig != null) {
                // 遭遇加一
                ShuShanRankActivityMgr.notifyFinishEncounterEvent(shuShanUserData.getUserId(), new ConditionTypeValueArgs(rewardConfig.getLevel(), 1));
                // 完成
//                ShuShanMgr.getLogger().info("蜀山完成修炼遭遇。活动id:{},玩家id:{},弟子id:{},格子id：{}，遭遇id:{},结束时间：{}，当前时间：{}", shuShanUserData.getActivityId(), shuShanUserData.getUserId(), disciple.getId(), grid.getGridId(), rewardConfig.getId(), endTime, now);
                grid.setLastFinishId(rewardConfig.getId());
                grid.getRecordInfoList().add(new ShuShanLiLianRecordInfo(rewardConfig.getId(), disciple.getName(), endTime));
                grid.setEndTime(0);
                // 尝试修炼下一个
                attemptStartLiLian(grid, disciple, endTime);
                return true;
            }
        }
        return false;
    }


    /**
     * 建筑升级
     */
    public ShuShanProto.ShuShanUpBuildRespMsg.Builder upBuild(GamePlayer player, int type) {
        ShuShanProto.ShuShanUpBuildRespMsg.Builder builder = ShuShanProto.ShuShanUpBuildRespMsg.newBuilder();
        Map<Integer, ShuShanBuildConfig> levelMap = ShuShanMgr.getConfig().getTypeLevelBuildMap().get(type);
        if (levelMap == null) {
            builder.setRet(GameErrorCode.E_SHUSHAN_THIS_BUILD_TYPE_NO_EXIST);
            return builder;
        }
        // 判断道具
        int oldLevel = getBuildLevel(type);
        if (levelMap.size() <= oldLevel) {
            // 满级了
            builder.setRet(GameErrorCode.E_SHUSHAN_THIS_BUILD_LEVEL_MAX);
            return builder;
        }
        ShuShanBuildConfig oldBuildConfig = levelMap.get(oldLevel);
        ShuShanBuildConfig newBuildConfig = levelMap.get(oldLevel + 1);
        if (newBuildConfig == null) {
            // 满级了
            builder.setRet(GameErrorCode.E_SHUSHAN_THIS_BUILD_LEVEL_MAX);
            return builder;
        }
        // 判断解锁条件
        if (newBuildConfig.getType() == eShuShanBuildType.type_6.getType()) {
            // 声望 解锁
            if (shuShanUserData.getPrestige() < newBuildConfig.getUnlock()) {
                builder.setRet(GameErrorCode.E_SHUSHAN_PRESTIGE_NO_ENOUGH);
                return builder;
            }
        } else {
            // 宗门解锁
            int typeLevel6 = getBuildLevel(eShuShanBuildType.type_6.getType());
            ShuShanBuildConfig lockConfig = ShuShanMgr.getConfig().getBuildConfigMap().get(newBuildConfig.getUnlock());
            if (lockConfig == null || typeLevel6 < lockConfig.getLevel()) {
                builder.setRet(GameErrorCode.E_SHUSHAN_UNLOCK_LIMIT);
                return builder;
            }
        }
        Property property = PropertyHelper.parseStringToProperty(oldBuildConfig.getUpgradCost());
        if (!player.getModule(CurrencyModule.class).removeCurrency(property, eLogMoneyType.ShuShan, eLogMoneyType.ShuShanUpBuildCost)) {
            builder.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
            return builder;
        }
        int now = DateHelper.getCurrentSecond();
        refreshExercise(now);
        ShuShanBuildData build = getBuilderData(type, now);
        build.setLevel(build.getLevel() + 1);
        if (build.getCurDiscipleId() > 0) {
            // 升级建筑 判断正在修炼的技能是否是最大等级的技能，如果不是，这个技能修炼成功 并且重新尝试修炼
            ShuShanDiscipleData disciple = discipleDataMap.get(build.getCurDiscipleId());
            //
            attemptFinishSkill(build, disciple);

            learnBuild(build, disciple);
        } else {
            build.setFreeTime(now);
            List<ShuShanProto.ShuShanGoodExerciseResult> list = touchGoodExercise(0);
            if (list.size() > 0) {
                builder.addAllGoodExerciseResultList(list);
            }
        }
        LogMgr.addLogShuShanBuildUp(new LogShuShanBuildUp(build.getActivityId(), build.getUserId(), build.getType(), shuShanUserData.getPrestige(), oldLevel, build.getLevel(), oldBuildConfig.getUpgradCost(), DateHelper.getCurrentTime()));
        player.notifyListener(eGamePlayerEventType.ShuShanBuildTotalLevel.getValue(), getAllBuildLevel());

        builder.addAllBuildInfoList(buildShuShanBuildInfoList());
        builder.setUserInfo(buildShuShanUserInfo());
        builder.addAllOwnDiscipleList(buildShuShanDiscipleInfoList());
        builder.setType(type);
        builder.setRet(0);
        return builder;
    }


    /**
     * 尝试完成技能
     * 刷新正在学习的技能
     * 1如果 出现 所学的技能  有更高的技能等级 直接完成
     * 2如果 待学的技能 有更高的技能等级出现 移除该节点 再末尾学习新增的技能
     */
    private void attemptFinishSkill(ShuShanBuildData build, ShuShanDiscipleData disciple) {
        if (build.getCurDiscipleId() <= 0 || build.getSuccessNodeList().size() <= 0) {
            return;
        }
        List<ShuShanBuildConfig> maxSkillBuildList = getTheBuildMaxSkillList(build);
        Iterator<ShuShanExerciseSuccessNode> iterator = build.getSuccessNodeList().iterator();
        boolean firstNode = true;
        while (iterator.hasNext()) {
            ShuShanExerciseSuccessNode node = iterator.next();
            // 正在学习的技能配置
            ShuShanSkillConfig nodeSkillConfig = ShuShanMgr.getConfig().getSkillConfigMap().get(node.getKillId());
            for (ShuShanBuildConfig maxSkillBuildConfig : maxSkillBuildList) {
                ShuShanSkillConfig maxSkillConfig = ShuShanMgr.getConfig().getSkillConfigMap().get(Integer.valueOf(maxSkillBuildConfig.getParam()));
                if (nodeSkillConfig.getLittleType() == maxSkillConfig.getLittleType() && nodeSkillConfig.getLevel() < maxSkillConfig.getLevel()) {
                    if (firstNode) {
                        int now = DateHelper.getCurrentSecond();
                        learnBuildSkill(disciple, build, node, now, !iterator.hasNext(), true, now);
                        moveForwardNode(build, node.getExerciseEndTime() - now, false);
                    }
                    iterator.remove();
                    return;
                }
            }
            firstNode = false;
        }
    }


    /**
     * 所有建筑的等级
     *
     * @return
     */
    private int getAllBuildLevel() {
        int totalLevel = 0;
        for (ShuShanBuildData buildData : buildDataMap.values()) {
            totalLevel += buildData.getLevel();
        }
        return totalLevel;
    }

    /**
     * 弟子招收和刷新
     *
     * @param player
     * @param type
     * @param index
     * @return
     */
    public ShuShanProto.ShuShanGetDiscipleRespMsg.Builder getDisciple(GamePlayer player, int type, int index) {
        ShuShanProto.ShuShanGetDiscipleRespMsg.Builder builder = ShuShanProto.ShuShanGetDiscipleRespMsg.newBuilder();
        if (type == 0) {
            // 判断上限
            if (discipleDataMap.size() >= getDiscipleMaxLimit()) {
                builder.setRet(GameErrorCode.E_SHUSHAN_DISCIPLE_NUM_LIMIT);
                return builder;
            }
            // 招收底子
            ShuShanDiscipleBaseInfo discipleBaseInfo = shuShanUserData.getDiscipleList().remove(index);
            if (discipleBaseInfo == null) {
                builder.setRet(GameErrorCode.E_SHUSHAN_DISCIPLE_NO_EXIST);
                return builder;
            }
            // 获得弟子
            ShuShanDiscipleData discipleData = new ShuShanDiscipleData();
            discipleData.setInsertOption();
            discipleData.setActivityId(shuShanUserData.getActivityId());
            discipleData.setUserId(shuShanUserData.getUserId());
            discipleData.setQuality(discipleBaseInfo.getQuality());
            discipleData.setGetTime(DateHelper.getCurrentSecond());
            discipleData.setId(maxId.incrementAndGet());
            discipleData.setName(discipleBaseInfo.getName());

            discipleBaseInfo.getPropertiesInfoMap().entrySet().forEach(e -> {
                discipleData.getPropertiesInfoMap().put(e.getKey(), new ShuShanPropertiesInfo(e.getValue(), 0));
            });
            discipleData.setLastLearnedTime(DateHelper.getCurrentSecond());
            discipleDataMap.put(discipleData.getId(), discipleData);
            // 刷新最大仙力
            refreshTotalMagic();
            LogMgr.addLogShuShanGetDisciple(new LogShuShanGetDisciple(shuShanUserData.getActivityId(), shuShanUserData.getUserId(), getBuildLevel(eShuShanBuildType.type_7.getType()), discipleData.getId(), discipleBaseInfo.getName(), discipleBaseInfo.getQuality(), getPropertiesTotalValue(discipleData.getPropertiesInfoMap()), new HashMap<>(discipleBaseInfo.getPropertiesInfoMap()), true, DateHelper.getCurrentTime()));
            // 刷新玩家修炼信息
            builder.addAllGoodExerciseResultList(touchGoodExercise(0));
            builder.addAllBuildInfoList(buildShuShanBuildInfoList());
            builder.addAllOwnDiscipleList(buildShuShanDiscipleInfoList());
        } else {
            // 刷新
            refreshGetTimes(true);
            if (shuShanUserData.getGetTimes() <= 0) {
                builder.setRet(GameErrorCode.E_SHUSHAN_GET_TIMES_NO_ENOUGH);
                return builder;
            }
            shuShanUserData.setGetTimes(shuShanUserData.getGetTimes() - 1);
            shuShanUserData.getDiscipleList().clear();
            refreshChooseDisciple(player.getLanguage());
        }
        builder.setUserInfo(buildShuShanUserInfo());
        builder.setRet(0);
        return builder;
    }


    /**
     * 购买选拔次数
     *
     * @param num
     * @return
     */
    public int addGetTimes(int num, boolean isBuy) {
        refreshGetTimes(false);
        shuShanUserData.setGetTimes(shuShanUserData.getGetTimes() + num);
        if (isBuy) {
            shuShanUserData.setBuyGetTimes(shuShanUserData.getBuyGetTimes() + num);
        }
        return 0;
    }

    /**
     * 刷新弟子 总仙力
     */
    private void refreshTotalMagic() {
        long totalValue = 0;
        for (ShuShanDiscipleData discipleData : discipleDataMap.values()) {
            totalValue += getPropertiesTotalValue(discipleData.getPropertiesInfoMap());
        }
        if (totalValue > shuShanUserData.getMaxMagic()) {
            shuShanUserData.setMaxMagic(totalValue);
            // 更新排行榜
            ShuShanRankActivityMgr.notifyRankEvent(shuShanUserData.getUserId(), totalValue, shuShanUserData.getPartyName());
        }
    }

    /**
     * 获取弟子的总属性
     *
     * @param disciple
     */
    private long getPropertiesTotalValue(ShuShanDiscipleData disciple) {
        long totalValue = 0;
        for (ShuShanPropertiesInfo item : disciple.getPropertiesInfoMap().values()) {
            totalValue += (item.getAddValue() + item.getBaseValue());
        }
        return totalValue;
    }

    private long getPropertiesTotalValue(Map<Integer, ShuShanPropertiesInfo> map) {
        long totalValue = 0;
        for (ShuShanPropertiesInfo item : map.values()) {
            totalValue += (item.getAddValue() + item.getBaseValue());
        }
        return totalValue;
    }

    /**
     * 获取某个属性的值
     *
     * @param disciple
     * @return
     */
    private long getPropertiesOneValue(ShuShanDiscipleData disciple, int type) {
        long value = 0;
        ShuShanPropertiesInfo propertiesInfo = disciple.getPropertiesInfoMap().get(type);
        if (propertiesInfo != null) {
            value = propertiesInfo.getBaseValue() + propertiesInfo.getAddValue();
        }
        return value;
    }

    /**
     * 尝试解锁修炼建筑
     */
    public void initBuild(GamePlayer player) {
        int now = DateHelper.getCurrentSecond();
        for (Integer type : ShuShanMgr.getConfig().getTypeLevelBuildListMap().keySet()) {
            getBuilderData(type, now);
        }
        player.notifyListener(eGamePlayerEventType.ShuShanBuildTotalLevel.getValue(), getAllBuildLevel());
    }

    private ShuShanBuildData getBuilderData(int type, int now) {
        ShuShanBuildData buildData = buildDataMap.get(type);
        if (buildData == null) {
            buildData = new ShuShanBuildData();
            buildData.setActivityId(shuShanUserData.getActivityId());
            buildData.setUserId(shuShanUserData.getUserId());
            buildData.setType(type);
            buildData.setLevel(1);
            buildData.setFreeTime(now);
            buildData.setInsertOption();
            buildDataMap.put(buildData.getType(), buildData);
        }
        return buildData;
    }

    /**
     * 刷新选拔弟子
     */
    public void refreshChooseDisciple(String language) {
        ShuShanBuildConfig config = getShuShanBuildConfigType7();
        if (config != null) {
            long now = DateHelper.getCurrentTime();
            for (int i = 0; i < config.getMaxStudent(); i++) {
                ShuShanDiscipleBaseInfo discipleBaseInfo = new ShuShanDiscipleBaseInfo();
                discipleBaseInfo.setName(NameMgr.getRandomName(eSexType.MALE, language));
                // 随机属性
                int totalValue = randomDisciplePropertiesInfo(discipleBaseInfo);
                shuShanUserData.getDiscipleList().add(discipleBaseInfo);
                shuShanUserData.setRandomDiscipleNum(shuShanUserData.getRandomDiscipleNum() + 1);

                // 加 未触发品质的次数
                for (int quality : config.getWeightMap().keySet()) {
                    int times = shuShanUserData.getUnTriggerQualityMap().getOrDefault(quality, 0);
                    shuShanUserData.getUnTriggerQualityMap().put(quality, times + 1);
                }
                shuShanUserData.getUnTriggerQualityMap().remove(discipleBaseInfo.getQuality());

                LogMgr.addLogShuShanGetDisciple(new LogShuShanGetDisciple(shuShanUserData.getActivityId(), shuShanUserData.getUserId(), config.getLevel(), i, discipleBaseInfo.getName(), discipleBaseInfo.getQuality(), totalValue, new HashMap<>(discipleBaseInfo.getPropertiesInfoMap()), false, now));
            }
        }
    }

    /**
     * 随机日常事件
     *
     * @return
     */
    public void randomDailyEventId(int now) {
        List<ShuShanEventConfig> list = ShuShanMgr.getConfig().getEventTypeConfigMap().get(eShuShanEventType.DAILY_EVENT.getType());
        if (list.size() <= 0) {
            return;
        }
        ShuShanEventConfig eventConfig = list.get(ShuShanMgr.getRandom().nextInt(list.size()));
        shuShanUserData.setEventRefreshTime(now);
        shuShanUserData.setCanReceiveEventId(eventConfig.getId());
    }

    /**
     * 删除某个弟子
     *
     * @param id
     */
    public void kickOutDisciple(int id) {
        // 删除正在修炼的弟子
        ShuShanDiscipleData discipleData = discipleDataMap.get(id);
        if (discipleData == null) {
            return;
        }
        int now = DateHelper.getCurrentSecond();
        int buildType = 0;
        Iterator<ShuShanBuildData> iterator = buildDataMap.values().iterator();
        while (iterator.hasNext()) {
            ShuShanBuildData buildData = iterator.next();
            if (buildData.getCurDiscipleId() == id) {
                // 删除预修炼的弟子
                buildData.setCurDiscipleId(0);
                buildData.getSuccessNodeList().clear();
                buildData.setFreeTime(now);
                buildData.setExerciseStartTime(0);
                buildType = buildData.getType();
                break;
            }
        }
        int liLianId = 0;
        // 结束正在历练的坑位
        ShuShanLiLianGridData gridData = getShuShanLiLianGridData(discipleData);
        if (gridData != null) {
            liLianId = gridData.getGridId();
            refreshLiLianGrid(gridData, now);
            gridData.setCurDiscipleId(0);
            if (gridData.getEndTime() > 0) {
                // 正在修炼
                gridData.setRemainTime(Math.max(0, gridData.getEndTime() - now));
                gridData.setEndTime(0);
            }
        }
        discipleData.setLastLearnedTime(now);
        discipleData.setIsDelete(true);
        discipleDataMap.remove(id);
        synchronized (deleteDiscipleDataMap) {
            deleteDiscipleDataMap.put(discipleData.getId(), discipleData);
        }
        LogMgr.addLogShuShanKickOutDisciple(new LogShuShanKickOutDisciple(shuShanUserData.getActivityId(), shuShanUserData.getUserId(), getBuildLevel(eShuShanBuildType.type_7.getType()), discipleData.getId(), discipleData.getQuality(), getPropertiesTotalValue(discipleData.getPropertiesInfoMap()), new HashMap<>(discipleData.getPropertiesInfoMap()), new HashMap<>(discipleData.getLearnedSkillMap()), buildType, liLianId, DateHelper.getCurrentTime()));
        // 重新排序
        refreshExercise(now);
    }

    /**
     * 获取当前弟子正在历练的格子
     *
     * @param disciple
     * @return
     */
    private ShuShanLiLianGridData getShuShanLiLianGridData(ShuShanDiscipleData disciple) {
        for (ShuShanLiLianGridData item : liLianGridDataMap.values()) {
            if (item.getCurDiscipleId() == disciple.getId()) {
                return item;
            }
        }
        return null;
    }

    /**
     * 领取事件奖励
     *
     * @param type
     */
    public ShuShanProto.ShuShanReceiveEventRewardRespMsg.Builder receiveEventReward(GamePlayer player, int type, int optionsId, int eventId) {
        ShuShanProto.ShuShanReceiveEventRewardRespMsg.Builder builder = ShuShanProto.ShuShanReceiveEventRewardRespMsg.newBuilder();
        String reward = null;
        int refreshTime = 0;
        if (type == eShuShanEventType.DAILY_EVENT.getType()) {
            int now = DateHelper.getCurrentSecond();
            long canReceiveTime = shuShanUserData.getEventRefreshTime() + ShuShanMgr.getConfig().getSHUSHAN_EVENT_DTIME() * DateHelper.MINUTE_SECONDS;
            if (now < canReceiveTime) {
                // CD 未到
                builder.setRet(GameErrorCode.E_SHUSHAN_NO_EVENT);
                return builder;
            }
            // 领取
            ShuShanEventConfig eventConfig = ShuShanMgr.getConfig().getEventConfigMap().get(shuShanUserData.getCanReceiveEventId());
            if (eventConfig == null) {
                // 奖励不存在
                builder.setRet(GameErrorCode.E_SHUSHAN_NO_EVENT);
                return builder;
            }
            reward = eventConfig.getOptionsRewardMap().get(optionsId);
            if (reward == null) {
                // 奖励不存在
                builder.setRet(GameErrorCode.E_SHUSHAN_OPTIONS_ID_ERROR);
                return builder;
            }
            eventId = shuShanUserData.getCanReceiveEventId();
            refreshTime = shuShanUserData.getEventRefreshTime();
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.ShuShan, eLogMoneyType.ShuShanReceiveDailyEventReward);
            randomDailyEventId(now);
        } else {
            // 判断是否有可领取的事件奖励
            ShuShanEventConfig eventConfig = ShuShanMgr.getConfig().getEventConfigMap().get(eventId);
            if (eventConfig == null) {
                // 奖励不存在
                builder.setRet(GameErrorCode.E_SHUSHAN_NO_EVENT);
                return builder;
            }
            if (shuShanUserData.getGrowEventFinishMap().containsKey(eventId)) {
                builder.setRet(GameErrorCode.E_SHUSHAN_RECEICED_REWARD);
                return builder;
            }
            if (eventConfig.getUnlock() > shuShanUserData.getPrestige()) {
                builder.setRet(GameErrorCode.E_SHUSHAN_NO_EVENT);
                return builder;
            }
            reward = eventConfig.getOptionsRewardMap().get(optionsId);
            if (reward == null) {
                // 奖励不存在
                builder.setRet(GameErrorCode.E_SHUSHAN_OPTIONS_ID_ERROR);
                return builder;
            }
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.ShuShan, eLogMoneyType.ShuShanReceiveGrowEventReward);
            shuShanUserData.getGrowEventFinishMap().put(eventId, optionsId);
            shuShanUserData.setUpdateOption();
        }
        LogMgr.addLogShuShanEventRecord(new LogShuShanEventRecord(shuShanUserData.getActivityId(), shuShanUserData.getUserId(), type, eventId, optionsId, reward, refreshTime, DateHelper.getCurrentSecond()));
        builder.setReward(reward);
        builder.setUserInfo(buildShuShanUserInfo());
        builder.setRet(0);
        return builder;
    }


    /**
     * 获取建筑 某个建筑的 技能等级
     *
     * @param disciple
     * @param type
     * @param littleType
     * @return
     */
    public int getDiscipleSkillLevel(ShuShanDiscipleData disciple, int type, int littleType, boolean newIfNull) {
        Map<Integer, Integer> map = disciple.getLearnedSkillMap().get(type);
        if (map == null && newIfNull) {
            map = new HashMap<>();
            disciple.getLearnedSkillMap().put(type, map);
            disciple.setUpdateOption();
        }
        if (map != null) {
            return map.getOrDefault(littleType, 0);
        }
        return 0;
    }

    /**
     * 领取引导奖励
     *
     * @param player
     */
    public ShuShanProto.ShuShanReceiveGuideRewardRespMsg.Builder receiveGuideReward(GamePlayer player) {
        ShuShanProto.ShuShanReceiveGuideRewardRespMsg.Builder builder = ShuShanProto.ShuShanReceiveGuideRewardRespMsg.newBuilder();
        if (shuShanUserData.getReceiveGuideReward()) {
            builder.setRet(GameErrorCode.E_SHUSHAN_RECEICED_REWARD);
            return builder;
        }
        player.getModule(CurrencyModule.class).addCurrency(ShuShanMgr.getConfig().getSHUSHAN_NEWGUIDE_REWARD(), eLogMoneyType.ShuShan, eLogMoneyType.ShuShanReceiveGuideReward);
        shuShanUserData.setReceiveGuideReward(true);
        builder.setReward(ShuShanMgr.getConfig().getSHUSHAN_NEWGUIDE_REWARD());
        builder.setUserInfo(buildShuShanUserInfo());
        builder.setRet(0);
        return builder;
    }

    /**
     * 获取历练格子信息
     *
     * @param id
     * @return
     */
    public ShuShanProto.ShuShanGetLiLianGridInfoRespMsg.Builder getLiLianGrad(int id) {
        ShuShanProto.ShuShanGetLiLianGridInfoRespMsg.Builder builder = ShuShanProto.ShuShanGetLiLianGridInfoRespMsg.newBuilder();
        refreshLiLianGrid(DateHelper.getCurrentSecond());
        if (id == 0) {
            liLianGridDataMap.values().forEach(e -> {
                builder.addGridInfoList(builderShuShanLiLianGridInfo(e));
            });
        } else {
            ShuShanLiLianGridData gridData = liLianGridDataMap.get(id);
            if (gridData != null) {
                builder.addGridInfoList(builderShuShanLiLianGridInfo(gridData));
            }
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 快速修行
     *
     * @param times 新增次数
     * @return
     */
    public List<ShuShanProto.ShuShanGoodExerciseResult> touchGoodExercise(int times) {
        int now = DateHelper.getCurrentSecond();
        refreshExercise(now);
        if (times > 0) {
            shuShanUserData.setGoodExerciseTimes(shuShanUserData.getGoodExerciseTimes() + times);
        }
        List<ShuShanProto.ShuShanGoodExerciseResult> resultList = new ArrayList<>();
        boolean isSettlement = true;
        while (shuShanUserData.getGoodExerciseTimes() > 0 && isSettlement) {
            isSettlement = false;
            for (ShuShanBuildData item : buildDataMap.values()) {
                if (item.getCurDiscipleId() > 0) {
                    // 快速修行
                    ShuShanDiscipleData disciple = discipleDataMap.get(item.getCurDiscipleId());
                    int cd = ShuShanMgr.getConfig().getLearnCDMap().get(disciple.getQuality());
                    Iterator<ShuShanExerciseSuccessNode> iterator = item.getSuccessNodeList().iterator();
                    while (iterator.hasNext() && shuShanUserData.getGoodExerciseTimes() > 0) {
                        ShuShanProto.ShuShanGoodExerciseResult.Builder result = ShuShanProto.ShuShanGoodExerciseResult.newBuilder();
                        ShuShanExerciseSuccessNode node = iterator.next();
                        int oldExerciseEndTime = node.getExerciseEndTime();
                        int needTimes = (node.getExerciseEndTime() - now + cd - 1) / cd;
                        if (needTimes < 0) {
                            // 做个保护 正常不会进来
                            needTimes = 0;
                        }
                        if (shuShanUserData.getGoodExerciseTimes() < needTimes) {
                            // 次数不够
                            node.setExerciseStartTime(now);
                            node.setExerciseEndTime(now + (needTimes - shuShanUserData.getGoodExerciseTimes()) * cd);
                            node.setGoodExerciseTimes(node.getGoodExerciseTimes() + shuShanUserData.getGoodExerciseTimes());
                            item.setUpdateOption();
                            moveForwardNode(item, oldExerciseEndTime - node.getExerciseEndTime(), false);

                            result.setExerciseTimes(shuShanUserData.getGoodExerciseTimes());
                            shuShanUserData.setGoodExerciseTimes(0);
                        } else {
                            iterator.remove();
                            // 成功学习了 该技能
                            node.setGoodExerciseTimes(node.getGoodExerciseTimes() + needTimes);
                            if (learnBuildSkill(disciple, item, node, now, !iterator.hasNext(), false, now)) {
                                isSettlement = true;
                            }
                            result.setExerciseTimes(needTimes);
                            result.addSkillId(node.getKillId());
                            shuShanUserData.setGoodExerciseTimes(shuShanUserData.getGoodExerciseTimes() - needTimes);
                            moveForwardNode(item, oldExerciseEndTime - now, true);
                        }
//                        ShuShanMgr.getLogger().info("蜀山执行快速修行。活动id:{},玩家id:{},弟子id:{},建筑id：{}，学习的技能id:{}，需要执行次数:{}，执行前的次数：{}，剩余次数：{}", shuShanUserData.getActivityId(), shuShanUserData.getUserId(), disciple.getId(), item.getType(), node.getKillId(), needTimes, oldGoodExerciseTimes, shuShanUserData.getGoodExerciseTimes());
                        result.setDiscipleId(disciple.getId());
                        resultList.add(result.build());
                    }
                }
            }
            if (isSettlement) {
                if (!attemptEnterBuild()) {
                    // 没有弟子进入修炼
                    break;
                }
            }
        }
        return resultList;
    }

    /**
     * 学习节点往前移动
     */
    private void moveForwardNode(ShuShanBuildData item, int time, boolean removeFirstNode) {
        for (int i = 0; i < item.getSuccessNodeList().size(); i++) {
            if (i == 0 && !removeFirstNode) {
                // 第一个不移动
                continue;
            }
            ShuShanExerciseSuccessNode node = item.getSuccessNodeList().get(i);
            node.setExerciseStartTime(node.getExerciseStartTime() - time);
            node.setExerciseEndTime(node.getExerciseEndTime() - time);
            item.setUpdateOption();
        }
    }


    /**
     * 派遣历练 / 或者 领取坑位奖励
     *
     * @param player
     * @param id
     * @param type       0领取坑位奖励  1 派遣历练   2表示领取遭遇奖励
     * @param discipleId
     * @return
     */
    public ShuShanProto.ShuShanDispatchLiLianRespMsg.Builder dispatch(GamePlayer player, int id, int type, int discipleId) {
        ShuShanProto.ShuShanDispatchLiLianRespMsg.Builder builder = ShuShanProto.ShuShanDispatchLiLianRespMsg.newBuilder();
        // 判断id 是否解锁
        ShuShanLiLianConfig liLianConfig = ShuShanMgr.getConfig().getLiLianConfigMap().get(id);
        if (liLianConfig == null) {
            builder.setRet(GameErrorCode.E_SHUSHAN_LILIAN_GRID_NO_EXIST);
            return builder;
        }
        if (liLianConfig.getUnlock() > shuShanUserData.getMaxMagic()) {
            builder.setRet(GameErrorCode.E_SHUSHAN_LILIAN_GRID_NO_UNLOCK);
            return builder;
        }
        if (liLianConfig.getType() != eShuShanLiLianGridType.LILIAN_GRID.getType() && liLianConfig.getType() != eShuShanLiLianGridType.REWARD_GRID.getType()) {
            builder.setRet(GameErrorCode.E_SHUSHAN_LILIAN_GRID_NO_CAN_ACTION);
            return builder;
        }
        ShuShanLiLianGridData grid = getLiLianGridData(id);
        if (type == 0) {
            if (liLianConfig.getType() != eShuShanLiLianGridType.REWARD_GRID.getType()) {
                builder.setRet(GameErrorCode.E_SHUSHAN_LILIAN_GRID_NO_REWARD);
                return builder;
            }
            if (grid.getReceivedId() == 1) {
                builder.setRet(GameErrorCode.E_SHUSHAN_RECEICED_REWARD);
                return builder;
            }
            OpenGoodsBagResult openGoodsBagResult = GoodsBagMgr.getRandomGoods(liLianConfig.getReward());
            player.getModule(CurrencyModule.class).addCurrency(openGoodsBagResult.getReward(), eLogMoneyType.ShuShan, eLogMoneyType.ShuShanReceiveLiLianGridReward);
            grid.setReceivedId(1);
            builder.setReward(PropertyHelper.parsePropertyToString(openGoodsBagResult.getReward()));
            builder.addGridInfo(builderShuShanLiLianGridInfo(grid));
        } else if (type == 1) {
            if (liLianConfig.getType() != eShuShanLiLianGridType.LILIAN_GRID.getType()) {
                builder.setRet(GameErrorCode.E_SHUSHAN_LILIAN_GRID_NO_CAN_ACTION);
                return builder;
            }
            if (grid.getCurDiscipleId() > 0) {
                builder.setRet(GameErrorCode.E_SHUSHAN_LILIAN_GRID_HAS_DISCIPLE);
                return builder;
            }
            ShuShanDiscipleData disciple = discipleDataMap.get(discipleId);
            if (disciple == null) {
                builder.setRet(GameErrorCode.E_SHUSHAN_DISCIPLE_NO_EXIST);
                return builder;
            }
            // 判断是否在历练中
            if (getShuShanLiLianGridData(disciple) != null) {
                builder.setRet(GameErrorCode.E_SHUSHAN_THE_DISCIPLE_ALREADY_LILIAN);
                return builder;
            }
            List<ShuShanRewardConfig> list = ShuShanMgr.getConfig().getActivityConditionInfoList(grid.getGridId());
            if (list == null) {
                builder.setRet(GameErrorCode.E_SHUSHAN_LILIAN_GRID_NO_ENCOUNTER);
                return builder;
            }
            // 判断是否修炼完
            if (list.get(list.size() - 1).getId() == grid.getLastFinishId()) {
                builder.setRet(GameErrorCode.E_SHUSHAN_LILIAN_GRID_HAS_FINISH);
                return builder;
            }
            grid.setCurDiscipleId(discipleId);
            // 刷新历练格子信息
            refreshLiLianGrid(grid, DateHelper.getCurrentSecond());
            builder.addGridInfo(builderShuShanLiLianGridInfo(grid));
        } else {
            // 领取历练遭遇奖励  领取该格子 全部可领取的
            // 领取的奖励配置
            Property reward = new Property();
            long now = DateHelper.getCurrentTime();
            for (ShuShanLiLianGridData item : liLianGridDataMap.values()) {
                ShuShanLiLianConfig lianConfig = ShuShanMgr.getConfig().getLiLianConfigMap().get(id);
                if (lianConfig.getType() != eShuShanLiLianGridType.LILIAN_GRID.getType()) {
                    continue;
                }
                refreshLiLianGrid(item, DateHelper.getCurrentSecond());
                // 刷新历练格子信息
                if (item.getLastFinishId() <= item.getReceivedId()) {
                    continue;
                }
                List<ShuShanRewardConfig> list = ShuShanMgr.getConfig().getActivityConditionInfoList(item.getGridId());
                if (list == null) {
                    continue;
                }
                ShuShanDiscipleData discipleData = discipleDataMap.get(item.getCurDiscipleId());
                long totalValue = 0;
                if (discipleData != null) {
                    totalValue = getPropertiesTotalValue(discipleData.getPropertiesInfoMap());
                }
                int receiveId = 0;
                for (ShuShanRewardConfig rewardConfig : list) {
                    if (item.getLastFinishId() < rewardConfig.getId()) {
                        // 未完成
                        break;
                    }
                    if (item.getReceivedId() < rewardConfig.getId()) {
                        Property property = PropertyHelper.parseStringToProperty(rewardConfig.getReward());
                        reward.addProperty(property);
                        receiveId = rewardConfig.getId();
                        LogMgr.addLogShuShanReceiveLiLianReward(new LogShuShanReceiveLiLianReward(shuShanUserData.getActivityId(), shuShanUserData.getUserId(), discipleData, totalValue, item.getGridId(), rewardConfig.getId(), rewardConfig.getReward(), now));
                    }
                }
                if (receiveId != 0) {
                    item.setReceivedId(receiveId);
                }
                builder.addGridInfo(builderShuShanLiLianGridInfo(item));
            }
            if (!reward.isNothing()) {
                player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.ShuShan, eLogMoneyType.ShuShanReceiveLiLianEncounterReward);
                builder.setReward(PropertyHelper.parsePropertyToString(reward));
            }
        }
        builder.setUserInfo(buildShuShanUserInfo());
        builder.setRet(0);
        return builder;
    }

    private ShuShanLiLianGridData getLiLianGridData(int id) {
        ShuShanLiLianGridData grid = liLianGridDataMap.get(id);
        if (grid == null) {
            grid = new ShuShanLiLianGridData();
            grid.setActivityId(shuShanUserData.getActivityId());
            grid.setUserId(shuShanUserData.getUserId());
            grid.setGridId(id);
            grid.setInsertOption();
            liLianGridDataMap.put(id, grid);
        }
        return grid;
    }

    /**
     * 购买消耗
     *
     * @return
     */
    public int buyGetTimesConsume(int num) {
        int consume = 0;
        refreshBuyGetRefreshTime();
        for (int i = 0; i < num; i++) {
            int times = shuShanUserData.getBuyGetTimes() + i;
            if (ShuShanMgr.getConfig().getCostGoldList().size() > times) {
                consume += ShuShanMgr.getConfig().getCostGoldList().get(times);
            } else {
                consume += ShuShanMgr.getConfig().getCostGoldList().get(ShuShanMgr.getConfig().getCostGoldList().size() - 1);
            }
        }
        return consume;
    }

    /**
     * 加声望
     *
     * @param num
     * @return
     */
    public long addPrestige(long num) {
        shuShanUserData.setPrestige(Math.max(0, shuShanUserData.getPrestige() + num));
        return shuShanUserData.getPrestige();
    }

    /**
     * 获取某个建筑的等级
     *
     * @param type
     * @return
     */
    public int getBuildLevel(int type) {
        ShuShanBuildData shuShanBuildData = buildDataMap.get(type);
        if (shuShanBuildData != null) {
            return shuShanBuildData.getLevel();
        }
        return 0;
    }

    /**
     * 是否有在修炼的弟子
     *
     * @return
     */
    public boolean hasExerciseDisciple() {
        for (ShuShanBuildData item : buildDataMap.values()) {
            if (item.getCurDiscipleId() > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param getLiLianInfoList 是否下发历练信息
     * @return
     */
    public ShuShanProto.ShuShanRespMsg.Builder builderShuShanRespMsg(boolean getLiLianInfoList) {
        ShuShanProto.ShuShanRespMsg.Builder builder = ShuShanProto.ShuShanRespMsg.newBuilder();
        // 玩家数据
        builder.setUserInfo(buildShuShanUserInfo());
        // 建筑数据
        builder.addAllBuildInfoList(buildShuShanBuildInfoList());
        // 弟子数据
        builder.addAllOwnDiscipleList(buildShuShanDiscipleInfoList());
        // 历练格子
        if (getLiLianInfoList) {
            builder.addAllLiLianInfoGridList(buildShuShanLiLianGridInfoList());
        }
        return builder;
    }

    private ShuShanProto.ShuShanLiLianGridInfo.Builder builderShuShanLiLianGridInfo(ShuShanLiLianGridData gridData) {
        ShuShanProto.ShuShanLiLianGridInfo.Builder builder = ShuShanProto.ShuShanLiLianGridInfo.newBuilder();
        builder.setId(gridData.getGridId());
        builder.setDiscipleId(gridData.getCurDiscipleId());
        builder.setLastFinishId(gridData.getLastFinishId());
        builder.setEndTime(gridData.getEndTime());
        builder.setReceivedId(gridData.getReceivedId());
        gridData.getRecordInfoList().forEach(e -> {
            builder.addRecordList(ShuShanProto.ShuShanLiLianRecordInfo.newBuilder().setId(e.getId()).setName(e.getName()));
        });
        builder.setRemainTIme(gridData.getRemainTime());
        return builder;
    }


    public ShuShanProto.ShuShanUserInfo.Builder buildShuShanUserInfo() {
        refreshBuyGetRefreshTime();
        refreshGetTimes(false);
        ShuShanProto.ShuShanUserInfo.Builder userInfo = ShuShanProto.ShuShanUserInfo.newBuilder();
        userInfo.setPrestige(shuShanUserData.getPrestige());
        userInfo.setMagic(shuShanUserData.getMaxMagic());
        userInfo.setGetTimes(shuShanUserData.getGetTimes());
        userInfo.setGetRefreshTime(shuShanUserData.getGetRefreshTime());
        userInfo.setBuyGetTimes(shuShanUserData.getBuyGetTimes());
        userInfo.setEventRefreshTime(shuShanUserData.getEventRefreshTime());
        userInfo.setCanReceiveEventId(shuShanUserData.getCanReceiveEventId());
        userInfo.setRandomDiscipleNum(shuShanUserData.getRandomDiscipleNum());
        shuShanUserData.getGrowEventFinishMap().entrySet().forEach(e -> {
            userInfo.addGrowEventFinishList(ShuShanProto.ShuShanGrowEventFinishInfo.newBuilder().setEventId(e.getKey()).setOptionsId(e.getValue()));
        });
        userInfo.setPartyName(shuShanUserData.getPartyName());
        userInfo.setFastExerciseTimes(shuShanUserData.getGoodExerciseTimes());
        userInfo.setReceiveGuideReward(shuShanUserData.getReceiveGuideReward());
        for (ShuShanDiscipleBaseInfo baseInfo : shuShanUserData.getDiscipleList()) {
            ShuShanProto.ShuShanDiscipleInfo.Builder disciple = ShuShanProto.ShuShanDiscipleInfo.newBuilder();
            disciple.setName(baseInfo.getName());
            disciple.setQuality(baseInfo.getQuality());

            baseInfo.getPropertiesInfoMap().entrySet().forEach(e -> {
                disciple.addProperties(ShuShanProto.ShuShanPropertiesInfo.newBuilder().setType(e.getKey()).setBaseValue(e.getValue()));
            });
            userInfo.addChooseDiscipleList(disciple);
        }
        return userInfo;
    }

    public List<ShuShanProto.ShuShanBuildInfo> buildShuShanBuildInfoList() {
        List<ShuShanProto.ShuShanBuildInfo> list = new ArrayList();
        for (ShuShanBuildData buildData : buildDataMap.values()) {
            ShuShanProto.ShuShanBuildInfo.Builder buildInfo = ShuShanProto.ShuShanBuildInfo.newBuilder();
            buildInfo.setType(buildData.getType());
            buildInfo.setLevel(buildData.getLevel());
            buildInfo.setCurDiscipleId(buildData.getCurDiscipleId());
            buildInfo.setExerciseStartTime(buildData.getExerciseStartTime());
            for (ShuShanExerciseSuccessNode node : buildData.getSuccessNodeList()) {
                ShuShanProto.ShuShanExerciseSuccessNode.Builder nodeBuild = ShuShanProto.ShuShanExerciseSuccessNode.newBuilder();
                nodeBuild.setKillId(node.getKillId());
                nodeBuild.setExerciseEndTime(node.getExerciseEndTime());
                nodeBuild.setExerciseStartTime(node.getExerciseStartTime());
                nodeBuild.setGoodExerciseTimes(node.getGoodExerciseTimes());
                buildInfo.addSuccessNodeList(nodeBuild);
            }
            list.add(buildInfo.build());
        }
        return list;
    }


    /**
     * @return
     */
    public List<ShuShanProto.ShuShanLiLianGridInfo> buildShuShanLiLianGridInfoList() {
        List<ShuShanProto.ShuShanLiLianGridInfo> list = new ArrayList<>();
        liLianGridDataMap.values().forEach(e -> {
            list.add(builderShuShanLiLianGridInfo(e).build());
        });
        return list;
    }

    public List<ShuShanProto.ShuShanDiscipleInfo> buildShuShanDiscipleInfoList() {
        List<ShuShanProto.ShuShanDiscipleInfo> list = new ArrayList();
        for (ShuShanDiscipleData item : discipleDataMap.values()) {
            ShuShanProto.ShuShanDiscipleInfo.Builder disciple = ShuShanProto.ShuShanDiscipleInfo.newBuilder();
            disciple.setId(item.getId());
            disciple.setName(item.getName());
            disciple.setQuality(item.getQuality());
            disciple.setGetTime(item.getGetTime());

            item.getPropertiesInfoMap().entrySet().forEach(e -> {
                disciple.addProperties(ShuShanProto.ShuShanPropertiesInfo.newBuilder().setType(e.getKey()).setBaseValue(e.getValue().getBaseValue()).setAddValue(e.getValue().getAddValue()));
            });
            for (Map.Entry<Integer, Map<Integer, Integer>> entry : item.getLearnedSkillMap().entrySet()) {
                int type = entry.getKey();
                for (Map.Entry<Integer, Integer> skillLevelEntry : entry.getValue().entrySet()) {
                    ShuShanProto.ShuShanDiscipleLearnedInfo.Builder builder = ShuShanProto.ShuShanDiscipleLearnedInfo.newBuilder();
                    builder.setType(type);
                    builder.setLittleType(skillLevelEntry.getKey());
                    builder.setLevel(skillLevelEntry.getValue());
                    disciple.addLearnedSkillList(builder);
                }
            }
            list.add(disciple.build());
        }
        return list;
    }

    public void setDiscipleDataMap(Map<Integer, ShuShanDiscipleData> discipleDataMap) {
        this.discipleDataMap = discipleDataMap;
    }

    public void setBuildDataMap(Map<Integer, ShuShanBuildData> buildDataMap) {
        this.buildDataMap = buildDataMap;
    }

    public void setLiLianGridDataMap(Map<Integer, ShuShanLiLianGridData> liLianGridDataMap) {
        this.liLianGridDataMap = liLianGridDataMap;
    }

    public void setMaxId(AtomicInteger maxId) {
        this.maxId = maxId;
    }

    public String getPartyName() {
        return shuShanUserData.getPartyName();
    }
}
